//
// Created by Administrator on 2025/2/25.
//

#include "ThreadPool.h"

Task::Task()
: _result(nullptr)
{

}

Task::~Task() {

}

void Task::exec() {
    if (_result != nullptr){
        _result->setValue(run());
    }
}

void Task::setResult(Result *result) {
    _result = result;
}

/****************************************************************************************/
// ThreadPool 类
/****************************************************************************************/
ThreadPool::ThreadPool()
    : _initThreadCount(0)
    , _taskCount(0)
    , _taskQueMaxThreshHold(TASK_MAX_THRESHHOLD)
    , _poolMode(PoolMode::MODE_FIXED)
    , _isRunning(false)
{

}

ThreadPool::~ThreadPool() {
    //线程池停止运行
    _isRunning = false;
}

void ThreadPool::setMode(PoolMode mode) {
    _poolMode = mode;
}

void ThreadPool::setTaskQueMaxThreshHold(int taskQueMaxThreshHold) {
    taskQueMaxThreshHold = taskQueMaxThreshHold;
}

void ThreadPool::start(int initThreadSize) {
    //记录线程个数
    _initThreadCount = initThreadSize;

    //创建线程对象
    for(int i = 0; i < _initThreadCount; i++){
        auto a = std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc,this));
        _threadVec.emplace_back(std::move(a));
    }

    //启动所有线程
    for(int i = 0; i < initThreadSize; i++){
        _threadVec[i]->start();
    }

    //线程池开始运行
    _isRunning = true;
}

//往任务队列中提交任务，这是生产者，要确保线程安全，提交一个任务的时候，返回值也绑定
Result ThreadPool::submitTask(std::shared_ptr<Task> sp) {
    if(sp.get() == nullptr){
        //任务不正确，直接返回
        std::cerr<<" submit task fail, task is null."<<std::endl;
        return Result(nullptr,false);
    }

    //获取锁
    std::unique_lock<std::mutex> lock(_taskQueMtx);

    //线程通信，需要任务队列有空余，有空余再放入队列
    if(!_notFull.wait_for(lock,std::chrono::seconds(1) ,[&]()->bool{
       return _taskQue.size() < _taskQueMaxThreshHold;
    })){
        //表示notFull等待1s，队列也没有空位
        std::cerr<<" task queue is full, submit task fail."<<std::endl;
        return Result(nullptr,false);
    }
    //放入队列
    _taskQue.emplace(sp);
    _taskCount = _taskQue.size();
    //通知消费者，可以消费
    _notEmpty.notify_all();
    //返回结果
    return Result(sp);
}

// 这是消费者
void ThreadPool::threadFunc() {
    while(_isRunning){
        std::shared_ptr<Task> task;
        {
            std::unique_lock<std::mutex> lock(_taskQueMtx);

            //如果是空的，就一直等待
            _notEmpty.wait(lock, [&]()->bool{
                return _taskQue.size() > 0;
            });


            //取任务
            task = _taskQue.front();
            _taskQue.pop();
            _taskCount = _taskQue.size();
            std::cout<<"get task success"<<std::endl;
            if(_taskCount > 0){
                //还有任务，通知消费者
                _notEmpty.notify_all();
            }

            //队列肯定不满了，可以让生产者生产
            _notFull.notify_all();
        }//在这里要释放锁，让别的线程能取任务

        if(task != nullptr){
            //当前线程执行这个任务
//            task->run();
            task->exec();
        }
    }
}


/****************************************************************************************/
// Result 类
/****************************************************************************************/
Result::Result(std::shared_ptr<Task> task,bool isDone)
: _task(task)
, _isDone(isDone)
{
    if (_task.get() != nullptr){
        _task->setResult(this);
    }
}

Result::~Result() {

}

void Result::setValue(Any any) {
    _any = std::move(any);
    _sem.post();
}

Any Result::get() {
    if (!_isDone){
        return "";
    }
    _sem.wait();
    return std::move(_any);
}
